package com.fdb.efp.batch.service.impl.bd;

import static com.fdb.basic.sequence.service.DefaultPatternDescriptor.DAY;
import static com.fdb.basic.sequence.service.DefaultPatternDescriptor.MONTH;
import static com.fdb.basic.sequence.service.DefaultPatternDescriptor.SEQ;
import static com.fdb.basic.sequence.service.DefaultPatternDescriptor.YEAR_4;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fdb.basic.framework.core.constant.MonAlrmLvlEnums.MonAlrmLvlEnum;
import com.fdb.basic.framework.core.util.DateTool;
import com.fdb.basic.framework.core.util.FileOperateUtil;
import com.fdb.basic.framework.core.util.ObjectReflectUtil;
import com.fdb.basic.framework.core.util.SFTPUtil;
import com.fdb.basic.framework.core.util.SpringContextUtils;
import com.fdb.basic.framework.core.util.StringUtil;
import com.fdb.basic.framework.core.util.UUIDUtil;
import com.fdb.basic.sequence.service.DefaultPatternDescriptor;
import com.fdb.basic.sequence.service.PatternDescriptor;
import com.fdb.basic.sequence.service.facade.PatternedLimitableSeqService;
import com.fdb.basic.sequence.service.facade.SequenceService;
import com.fdb.efp.batch.common.constant.HjPrdBizEnums;
import com.fdb.efp.batch.service.facade.bd.BdAccLedgerBatchService;
import com.fdb.efp.batch.service.util.DueDataUtil;
import com.fdb.efp.esb.service.bo.req.hj.ReqDownLoadFileBean;
import com.fdb.efp.esb.service.facade.hj.DownLoadFileService;
import com.fdb.efp.loan.service.facade.AccoutErroTempService;
import com.fdb.efp.loan.service.facade.BdAccLedgerDetailInfoService;
import com.fdb.efp.loan.service.facade.BdAccLedgerService;
import com.fdb.efp.loan.service.facade.BdAccLedgerTempService;
import com.fdb.efp.loan.service.vo.AccoutErroTempVO;
import com.fdb.efp.loan.service.vo.BdAccLedgerDetailInfoVO;
import com.fdb.efp.loan.service.vo.BdAccLedgerTempVO;
import com.fdb.efp.loan.service.vo.BdAccLedgerVO;
import com.fdb.efp.loan.service.vo.BdNewAccLedgerVO;
import com.fdb.efp.nls.common.constant.PrdInfoEnum;

/**
 * 
 * 根据百度同步过来的并账文件信息临时表数据同步到百度并账文件标准化表
 * 
 * @author ludayong
 * @since 2019年3月9日 上午10:42:22
 * @version 1.0
 */
@Service("bdAccLedgerBatchService")
public class BdAccLedgerBatchServiceImpl implements BdAccLedgerBatchService {

	private static Logger logger = LoggerFactory.getLogger(BdAccLedgerBatchServiceImpl.class);

	private String ledgerFileName = "IFP_UL_0101_OCM_PBD002_";// 标准化文件名称

	private String prtnrCd = "002";// 合作方代码

	private String prodType = "10002002";// 产品类型

	private static final String DATA_SEPARATOR = "|";// 数据分隔符

	private static final String DATA_SEPARATOR_C = ",";// 数据分隔符

	private static final String TXT_SUFFIX = ".txt";// txt文件后缀

	private static final String OK_SUFFIX = ".ok";// ok文件后缀

	private static final int BD_ACC_LEDGER_NUM = 14;// 百度并账文件标准化信息数量

	private static final int BD_ACC_LEDGER_COLNUM = 15;// 百度并账文件列数

	private static final String SER_NUM_01 = ".01";// 百度并账文件序号

	private static final String SER_NUM_02 = ".02";// 百度并账文件序号

	private static final String TYPE_LE = "LE";// 试单业务

	private static final String TYPE_LF = "LF";// 正式业务

	private static final PatternDescriptor PATTERN_LE = DefaultPatternDescriptor.of("LE" + YEAR_4 + MONTH + DAY + SEQ, 8);

	private static final PatternDescriptor PATTERN_LF = DefaultPatternDescriptor.of("LF" + YEAR_4 + MONTH + DAY + SEQ, 8);

	@Value("${analysis.accLedgerFilePathBaidu}")
	private String accLedgerFilePath;// 生成的并账文件存放路径

	@Value("${analysis.accLedgerFileRemotePathBaidu}")
	private String accLedgerFileRemotePathBaidu;// 并账文件上传到文件服务器的路径

	@Value("${analysis.accFilePathBaidu}")
	private String accFilePathBaidu;// 百度账务文件解析地址

	@Value("${analysis.accLedgerFileName}")
	private String accLedgerFileName;// 百度并账文件名称

	// sftp用户名
	@Value("${analysis.hjUserName}")
	private String userName;

	// sftp密码
	@Value("${analysis.hjPassword}")
	private String password;

	// sftp主机ip
	@Value("${analysis.hjFtpHost}")
	private String ftpHost;

	// sftp主机端口
	@Value("${analysis.hjFtpPort}")
	private int ftpPort;

	@Autowired
	@Qualifier("bdAccLedgerTempService")
	private BdAccLedgerTempService bdAccLedgerTempService;// 百度并账临时信息

	@Autowired
	@Qualifier("bdAccLedgerDetailInfoService")
	private BdAccLedgerDetailInfoService bdAccLedgerDetailInfoService;// 百度并账详细信息

	@Autowired
	@Qualifier("bdAccLedgerService")
	private BdAccLedgerService bdAccLedgerService;// 百度并账文件标准化信息

	@Autowired
	@Qualifier("accoutErroTempService")
	private AccoutErroTempService accoutErroTempService;// 错误信息

	@Autowired
	@Qualifier("downLoadFileService")
	private DownLoadFileService downLoadFileService;// 贷款文件下载通知

	@Autowired
	@Qualifier("dbSeqService")
	private SequenceService sequenceService;// sequence服务

	// 百度并账信息指标
	public static Map<String, String> indexMap = new HashMap<String, String>();
	static {
		indexMap.put("intoOverdueRemainPrincipalLong", "intoOverdueRemainPrincipalLong");
		indexMap.put("intoOverdueRemainPrincipalShort", "intoOverdueRemainPrincipalShort");
		indexMap.put("loanFlushPrincipalLong", "loanFlushPrincipalLong");
		indexMap.put("loanFlushPrincipalShort", "loanFlushPrincipalShort");
		// indexMap.put("loaningPrincipalLong", "loaningPrincipalLong");
		// indexMap.put("loaningPrincipalShort", "loaningPrincipalShort");
		indexMap.put("loanPrincipalLong", "loanPrincipalLong");
		indexMap.put("loanPrincipalShort", "loanPrincipalShort");
		indexMap.put("provisionInterest", "provisionInterest");
		indexMap.put("provisionPenalty", "provisionPenalty");
		indexMap.put("repayInterest", "repayInterest");
		indexMap.put("repayNormalPrincipalLong", "repayNormalPrincipalLong");
		indexMap.put("repayNormalPrincipalShort", "repayNormalPrincipalShort");
		indexMap.put("repayOverduePrincipal", "repayOverduePrincipal");
		indexMap.put("repayPenalty", "repayPenalty");
		indexMap.put("violate", "violate");
	}

	/**
	 * 
	 * 根据百度同步过来的并账文件信息临时表数据生成百度并账文件标准化表 <br>
	 * 0.1:ludayong:2019年3月9日 上午10:48:33:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年3月9日 上午10:48:33
	 * @date 2019年3月9日 上午10:48:33
	 * @version 0.1
	 */
	@SuppressWarnings("rawtypes")
	@Transactional
	public boolean batchUpdateAccLedger(String curDate, String prdCode, String type) throws Exception {
		boolean result = false;
		long startTime = System.currentTimeMillis();
		logger.info("同步百度并账文件信息临时数据到百度并账文件标准化表：[" + DateTool.formatDate(new Date(startTime), DateTool.PATTERN_DATETIME) + "]， 处理开始");

		// 校验百度并账文件处理入参信息是否正确
		if (!checkParamInfo(curDate, prdCode, type)) {
			return result;
		}
		// 标准化文件名称 满易贷 IFP_UL_0101_OCM_PBD002_
		// 合作方编码 002-度小满
		// 互金产品类型 10002002-度小满满易贷 10002003 -度小满尊享贷
		if (PrdInfoEnum.MYD.getPrdId().equals(prdCode)) {// 满易贷
			prodType = HjPrdBizEnums.PrdCodeEnum.PRD_CODE_MYD.getValue();
		} else if (PrdInfoEnum.ZXD.getPrdId().equals(prdCode)) {// 尊享贷
			prodType = HjPrdBizEnums.PrdCodeEnum.PRD_CODE_ZXD.getValue();
		}
		try {
			// 通过存储过程初始化百度并账文件标准化信息
			try {
				bdAccLedgerService.initNBdAccLedgerInfo();
			} catch (Exception e) {
				String tableName = "bd_acc_ledger";
				String errorMsg = "产品编号：" + prdCode + "，存储过程初始化百度并账文件标准化信息出错，错误信息：" + e.getMessage();
				addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, errorMsg);
				logger.error(errorMsg);
				e.printStackTrace();
				return result;
			}

			// 校验百度并账文件标准化信息是否正确
			if (!checkBdAccLedgerListInfo()) {
				return result;
			}

			// 百度并账文件标准化信息
			BdAccLedgerVO bdAccLedgerVo = new BdAccLedgerVO();
			// 合作方代码
			bdAccLedgerVo.setPartnerCode(prtnrCd);
			// 产品类型
			bdAccLedgerVo.setProdType(prodType);
			List<BdNewAccLedgerVO> bdAccLedgerList = bdAccLedgerService.queryAllBdAccLedger(bdAccLedgerVo);
			if (Objects.nonNull(bdAccLedgerList) && bdAccLedgerList.size() != BD_ACC_LEDGER_NUM) {
				String tableName = "bd_acc_ledger";
				String errorMsg = "百度并账文件标准化信息数目不对，正确数目：" + BD_ACC_LEDGER_NUM + "，实际数目：" + bdAccLedgerList.size();
				addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, errorMsg);
				logger.error(errorMsg);
				return result;
			}

			// 百度并账文件路径
			String filePath = accFilePathBaidu + prdCode + File.separator + curDate + File.separator + accLedgerFileName;
			// 校验并账文件是否正确
			if (!checkAccLedgerFile(filePath)) {
				return result;
			}

			// 查询账务日期需要处理的并账文件信息临时表信息
			BdAccLedgerTempVO bdAccLedgerTempVo = new BdAccLedgerTempVO();
			bdAccLedgerTempVo.setCurDate(curDate);
			if (PrdInfoEnum.MYD.getPrdId().equals(prdCode)) {// 满易贷
				bdAccLedgerTempVo = bdAccLedgerTempService.queryByPkMYD(bdAccLedgerTempVo);
			} else if (PrdInfoEnum.ZXD.getPrdId().equals(prdCode)) {// 尊享贷
				bdAccLedgerTempVo = bdAccLedgerTempService.queryByPkZXD(bdAccLedgerTempVo);
			}
			// 需要更新百度并账文件标准化信息
			List<BdAccLedgerVO> bdInfoUpdateList = new ArrayList<BdAccLedgerVO>();
			if (Objects.nonNull(bdAccLedgerTempVo)) {
				try {
					// 获取并账文件指标信息
					Map map = ObjectReflectUtil.getKeyAndValue(bdAccLedgerTempVo);
					Iterator entries = map.entrySet().iterator();
					while (entries.hasNext()) {
						Entry entry = (Entry) entries.next();
						// 键
						String key = (String) entry.getKey();
						// 排除以下两个非并账信息的指标
						if ("serialVersionUID".equals(key) || "curDate".equals(key)) {
							continue;
						}
						// 值
						Object value = entry.getValue();
						// 需要更新百度并账文件标准化信息
						BdAccLedgerVO bdAccLedgerVO = new BdAccLedgerVO();
						// 指标代码
						bdAccLedgerVO.setIndexCode(key);
						// 渠道日期
						bdAccLedgerVO.setChannelDate(bdAccLedgerTempVo.getCurDate());

						if (PrdInfoEnum.MYD.getPrdId().equals(prdCode)) {// 满易贷
							bdAccLedgerVO.setProdType(HjPrdBizEnums.PrdCodeEnum.PRD_CODE_MYD.getValue());
						} else if (PrdInfoEnum.ZXD.getPrdId().equals(prdCode)) {// 尊享贷
							bdAccLedgerVO.setProdType(HjPrdBizEnums.PrdCodeEnum.PRD_CODE_ZXD.getValue());
						}
						if (Objects.nonNull(value) && !StringUtil.isNullorBank(value.toString())) {
							// 交易金额
							bdAccLedgerVO.setAmount(DueDataUtil.checkDecimalInfo(new BigDecimal(value.toString()), 100));
						} else {
							String tableName = "bd_acc_ledger";
							String errorMsg = "百度并账信息字段：[" + key + "]，值为空：[" + value + "]";
							addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, errorMsg);
							logger.error(errorMsg);
							return result;
						}
						bdInfoUpdateList.add(bdAccLedgerVO);
					}
				} catch (InvocationTargetException e) {
					String tableName = "bd_acc_ledger";
					String errorMsg = "产品编号：" + prdCode + "，初始化百度并账文件标准化信息出错，错误信息：" + e.getMessage();
					addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, errorMsg);
					logger.error(errorMsg);
					e.printStackTrace();
				}
			} else {
				String tableName = "bd_acc_ledger";
				String errorMsg = "百度并账文件信息为空，产品编号" + prdCode;
				addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, errorMsg);
				logger.error(errorMsg);
				return result;
			}
			if (!bdInfoUpdateList.isEmpty()) {
				for (BdAccLedgerVO bdAccLedgerVO : bdInfoUpdateList) {
					// 根据指标代码和产品类型查询百度并账文件标准化信息对应信息是否存在
					BdAccLedgerVO queryBdAccLedgerVO = bdAccLedgerService.queryByPk(bdAccLedgerVO);
					if (Objects.nonNull(queryBdAccLedgerVO)) {
						int num = bdAccLedgerService.updateByPk(bdAccLedgerVO);
						logger.info("百度并账文件标准化信息更新结果，num：【" + num + "】");
						if (num != 1) {
							String tableName = "bd_acc_ledger";
							String errorMsg = "更新百度并账文件标准化信息出错，指标代码：" + bdAccLedgerVO.getIndexCode() + "，产品编号" + prdCode;
							addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, errorMsg);
							logger.error(errorMsg);
							return result;
						}
					} else {
						String tableName = "bd_acc_ledger";
						String errorMsg = "未查询到百度并账文件标准化信息，指标代码：" + bdAccLedgerVO.getIndexCode() + "，产品编号" + prdCode;
						addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, errorMsg);
						logger.error(errorMsg);
					}
				}
			}
			if (Objects.nonNull(bdAccLedgerTempVo)) {
				// 初始化百度并账详细信息
				BdAccLedgerDetailInfoVO bdAccLedgerDetailInfo = initBdAccLedgerDetailInfo(bdAccLedgerTempVo, prdCode, type);
				if (Objects.nonNull(bdAccLedgerDetailInfo)) {
					BdAccLedgerDetailInfoVO inBdAccLedgerDetailInfoVO = new BdAccLedgerDetailInfoVO();
					// 产品编号
					inBdAccLedgerDetailInfoVO.setPrdCode(bdAccLedgerDetailInfo.getPrdCode());
					// 账务日期
					inBdAccLedgerDetailInfoVO.setCurDate(bdAccLedgerDetailInfo.getCurDate());
					// 业务类型
					inBdAccLedgerDetailInfoVO.setType(type);
					// 业务类型
					bdAccLedgerDetailInfo.setType(type);
					// 根据指标代码和账务日期查询百度并账详细信息是否存在
					BdAccLedgerDetailInfoVO queryBdAccLedgerDetailInfoVO = bdAccLedgerDetailInfoService
							.queryByPk(inBdAccLedgerDetailInfoVO);
					if (Objects.nonNull(queryBdAccLedgerDetailInfoVO)) {
						String tableName = "bd_acc_ledger_detail_info";
						String errorMsg = "百度并账明细信息已推送互金并账处理，产品编号：" + bdAccLedgerDetailInfo.getPrdCode() + "，账务日期"
								+ bdAccLedgerDetailInfo.getCurDate();
						addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, errorMsg);
						logger.error(errorMsg);
						return result;
					} else {
						int num = bdAccLedgerDetailInfoService.insertBdAccLedgerDetailInfo(bdAccLedgerDetailInfo);
						logger.info("百度并账详细信息新增结果，num：【" + num + "】");
						if (num != 1) {
							String tableName = "bd_acc_ledger_detail_info";
							String errorMsg = "新增百度并账详细信息，产品编号：" + bdAccLedgerDetailInfo.getPrdCode() + "，账务日期"
									+ bdAccLedgerDetailInfo.getCurDate();
							addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, errorMsg);
							logger.error(errorMsg);
						} else {
							result = true;
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			String tableName = "bd_acc_ledger";
			String errorMsg = "同步百度并账文件信息临时数据到百度并账文件标准化表出错";
			String remark = "同步百度并账文件信息临时数据到百度并账文件标准化表出错，错误信息：" + e.getMessage();
			addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, remark);
			logger.error(remark);
			throw new Exception(remark);
		}
		long endTime = System.currentTimeMillis();
		logger.info("同步百度并账文件信息临时数据到百度并账文件标准化表：[" + DateTool.formatDate(new Date(endTime), DateTool.PATTERN_DATETIME) + "]， 处理结束");
		logger.info("同步百度并账文件信息临时数据到百度并账文件标准化表，耗时：[" + (endTime - startTime) / 1000.0 + "]秒，处理结果[" + result + "]");
		return result;
	}

	/**
	 * 
	 * 生成百度并账文件标准化文件 <br>
	 * 0.1:ludayong:2019年3月9日 下午2:30:13:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年3月9日 下午2:30:13
	 * @date 2019年3月9日 下午2:30:13
	 * @version 0.1
	 */
	public boolean createBdAccLedgerFile(String curDate, String prdCode, String type) {
		boolean reslut = false;
		// 校验百度并账文件处理入参信息是否正确
		if (!checkParamInfo(curDate, prdCode, type)) {
			return reslut;
		}
		// 查询账务日期需要处理的并账文件信息临时表信息
		BdAccLedgerTempVO bdAccLedgerTempVo = new BdAccLedgerTempVO();
		bdAccLedgerTempVo.setCurDate(curDate);
		if (PrdInfoEnum.MYD.getPrdId().equals(prdCode)) {// 满易贷
			bdAccLedgerTempVo = bdAccLedgerTempService.queryByPkMYD(bdAccLedgerTempVo);
		} else if (PrdInfoEnum.ZXD.getPrdId().equals(prdCode)) {// 尊享贷
			bdAccLedgerTempVo = bdAccLedgerTempService.queryByPkZXD(bdAccLedgerTempVo);
		}

		// 互金产品类型 10002002-度小满满易贷 10002003 -度小满尊享贷
		if (PrdInfoEnum.MYD.getPrdId().equals(prdCode)) {// 满易贷
			prodType = HjPrdBizEnums.PrdCodeEnum.PRD_CODE_MYD.getValue();
		} else if (PrdInfoEnum.ZXD.getPrdId().equals(prdCode)) {// 尊享贷
			prodType = HjPrdBizEnums.PrdCodeEnum.PRD_CODE_ZXD.getValue();
		}

		if (Objects.nonNull(bdAccLedgerTempVo)) {
			try {
				File file = null;
				// 百度并账文件标准化文件名
				String fileName = "";
				// 百度并账文件标准化ok文件名
				String okFileName = "";
				// 查询百度并账文件标准化数据
				BdAccLedgerVO bdAccLedgerVo = new BdAccLedgerVO();
				// 合作方代码
				bdAccLedgerVo.setPartnerCode(prtnrCd);
				// 产品类型
				bdAccLedgerVo.setProdType(prodType);
				List<BdNewAccLedgerVO> bdAccLedgerList = bdAccLedgerService.queryAllBdAccLedger(bdAccLedgerVo);

				if (Objects.nonNull(bdAccLedgerList) && bdAccLedgerList.size() == BD_ACC_LEDGER_NUM) {
					logger.info("百度并账文件标准化数据，数目【" + bdAccLedgerList.size() + "】");
					// 存放百度并账文件标准化路径
					String localUploadPath = accLedgerFilePath;
					logger.info("存放百度并账文件标准化路径：" + accLedgerFilePath);
					String changeDate = bdAccLedgerList.get(0).getChannelDate();
					if (!StringUtil.isNullorBank(changeDate) && changeDate.length() != 8) {
						String tableName = "bd_acc_ledger";
						String errorMsg = "生成百度并账文件标准化文件：校验账务日期格式不正确";
						addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, errorMsg);
						logger.error(errorMsg);
						return reslut;
					}
					// 百度并账文件标准化文件名
					if (PrdInfoEnum.MYD.getPrdId().equals(prdCode)) {// 满易贷
						fileName = ledgerFileName + curDate + SER_NUM_01 + TXT_SUFFIX;
						okFileName = ledgerFileName + curDate + SER_NUM_01 + OK_SUFFIX;
					} else if (PrdInfoEnum.ZXD.getPrdId().equals(prdCode)) {// 尊享贷
						fileName = ledgerFileName + curDate + SER_NUM_02 + TXT_SUFFIX;
						okFileName = ledgerFileName + curDate + SER_NUM_02 + OK_SUFFIX;
					}

					file = FileOperateUtil.writeTxt(localUploadPath + fileName, bdAccLedgerList, DATA_SEPARATOR);
					if (file != null) {
						// 百度并账文件生成成功后，生成ok文件
						String ok = "OCM_acc_ledger_download_file_temp=" + bdAccLedgerList.size();
						File fileOk = DueDataUtil.writeOk(localUploadPath + okFileName, ok);
						if (fileOk != null) {
							// 把生成的百度并账文件放到文件服务器上，通知互金获取
							// 上传路径
							String fileNameFromPath = localUploadPath + fileName;
							logger.info("上传路径:" + fileNameFromPath);
							boolean fileUploadRs = upLoadAccLedgerFile(fileName, fileNameFromPath);
							logger.info("上传百度并账文件结果:" + fileUploadRs);
							if (fileUploadRs) {
								// 并账文件上传成功后上传ok文件
								String fileNameFromPathOk = localUploadPath + okFileName;// 全路径
								boolean fileUploadOK = upLoadAccLedgerFile(okFileName, fileNameFromPathOk);
								if (fileUploadOK) {
									logger.info("调用通知互金接口开始");
									ReqDownLoadFileBean reqDownLoadFileBean = new ReqDownLoadFileBean();
									// 文件名称
									reqDownLoadFileBean.setFileNm(fileName);
									reqDownLoadFileBean.setProdType(prodType);
									// 001-马上贷 002-度小满
									reqDownLoadFileBean.setPrtnrCd(prtnrCd);

									boolean rs = downLoadFileService.DownLoadFileNotice(reqDownLoadFileBean);
									if (!rs) {
										reslut = false;
										String tableName = "bd_acc_ledger";
										String errorMsg = "通知互金获取并账文件失败";
										addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, errorMsg);
										logger.error(errorMsg);
									} else {
										reslut = true;
									}
									logger.info("调用通知互金接口结束");
								}
							}
						}
					} else {
						String tableName = "bd_acc_ledger";
						String errorMsg = "生成百度并账文件标准化文件失败";
						addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, errorMsg);
						logger.error(errorMsg);
						return reslut;
					}
				} else {
					String tableName = "bd_acc_ledger";
					String errorMsg = "百度并账文件标准化信息数目不对，正确数目：" + BD_ACC_LEDGER_NUM + "，实际数目：" + bdAccLedgerList.size();
					addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, errorMsg);
					logger.error(errorMsg);
					return reslut;
				}
				logger.info("生成百度并账文件标准化文件成功：" + file == null ? "文件为空" : file.getPath());
			} catch (Exception e) {
				reslut = false;
				String tableName = "bd_acc_ledger";
				e.printStackTrace();
				String errorMsg = "生成百度并账文件标准化文件失败：" + e.getMessage();
				addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, errorMsg);
				logger.error(errorMsg);
			}
		}
		return reslut;
	}

	/**
	 * 
	 * 上传百度并账文件到文件服务器 <br>
	 * 0.1:ludayong:2019年3月9日 上午10:45:35:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年3月9日 上午10:45:35
	 * @date 2019年3月9日 上午10:45:35
	 * @version 0.1
	 */
	private boolean upLoadAccLedgerFile(String fileName, String fileNameFromPath) {
		SFTPUtil sftpUtil = null;
		boolean fileUpFlag = false;
		try {
			// 连接文件服务器，上传并账文件到文件服务器
			String hjFtpUserName = userName;
			String hjFtpUserPwd = password;
			String hjIp = ftpHost;
			int hjPort = ftpPort;
			sftpUtil = new SFTPUtil(hjFtpUserName, hjFtpUserPwd, hjIp, hjPort);
			String filePathTo = accLedgerFileRemotePathBaidu;
			logger.info("文件服务器信息：" + hjFtpUserName + "" + hjIp + " " + hjPort);
			logger.info("文件服务器的存放文件位置：" + filePathTo);
			fileUpFlag = sftpUtil.upFile(filePathTo, fileName, fileNameFromPath, true, false);
		} catch (Exception e) {
			e.printStackTrace();
			String errorMsg = "上传百度并账文件到文件服务器出错";
			String remark = "上传百度并账文件到文件服务器出错，错误信息：" + e.getMessage();
			String tableName = "bd_acc_ledger";
			addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, remark);
			logger.error(remark);
		}
		return fileUpFlag;
	}

	/**
	 * 
	 * 初始化百度并账详细信息 <br>
	 * 0.1:ludayong:2019年4月15日 上午9:03:27:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年4月15日 上午9:03:27
	 * @date 2019年4月15日 上午9:03:27
	 * @version 0.1
	 */
	public BdAccLedgerDetailInfoVO initBdAccLedgerDetailInfo(BdAccLedgerTempVO bdAccLedgerTempVo, String prdCode, String type) {
		// 百度并账详细信息
		BdAccLedgerDetailInfoVO bdAccLedgerDetailInfoVO = new BdAccLedgerDetailInfoVO();
		// 单位转换
		final int oneHundred = 100;
		String seqNo = "";
		if (TYPE_LE.equals(type)) {
			seqNo = generateSeqNo(TYPE_LE, PATTERN_LE);
		} else if (TYPE_LF.equals(type)) {
			seqNo = generateSeqNo(TYPE_LF, PATTERN_LF);
		}
		if (StringUtil.isNullorBank(seqNo)) {
			seqNo = UUIDUtil.getUUID();
		}
		// seq_no 流水号
		bdAccLedgerDetailInfoVO.setSeqNo(seqNo);
		// prd_code 产品编号
		bdAccLedgerDetailInfoVO.setPrdCode(prdCode);
		// cur_date 账务日期
		bdAccLedgerDetailInfoVO.setCurDate(DueDataUtil.dateInfoTrans(bdAccLedgerTempVo.getCurDate()));
		// loan_principal_short 短期贷款本金放款金额
		bdAccLedgerDetailInfoVO.setLoanPrincipalShort(DueDataUtil.checkDecimalInfo(bdAccLedgerTempVo.getLoanPrincipalShort(), oneHundred));
		// loaning_principal_short 短期贷款本金放款中金额
		// bdAccLedgerDetailInfoVO
		// .setLoaningPrincipalShort(DueDataUtil.checkDecimalInfo(bdAccLedgerTempVo.getLoaningPrincipalShort(),
		// oneHundred));
		// loan_flush_principal_short 短期贷款本金撤销金额
		bdAccLedgerDetailInfoVO
				.setLoanFlushPrincipalShort(DueDataUtil.checkDecimalInfo(bdAccLedgerTempVo.getLoanFlushPrincipalShort(), oneHundred));
		// repay_normal_principal_short 短期正常本金还款
		bdAccLedgerDetailInfoVO
				.setRepayNormalPrincipalShort(DueDataUtil.checkDecimalInfo(bdAccLedgerTempVo.getRepayNormalPrincipalShort(), oneHundred));
		// loan_principal_long 中长期贷款本金放款金额
		bdAccLedgerDetailInfoVO.setLoanPrincipalLong(DueDataUtil.checkDecimalInfo(bdAccLedgerTempVo.getLoanPrincipalLong(), oneHundred));
		// loaning_principal_long 中长期贷款本金放款中金额
		// bdAccLedgerDetailInfoVO
		// .setLoaningPrincipalLong(DueDataUtil.checkDecimalInfo(bdAccLedgerTempVo.getLoaningPrincipalLong(),
		// oneHundred));
		// loan_flush_principal_long 中长期贷款本金撤销金额
		bdAccLedgerDetailInfoVO
				.setLoanFlushPrincipalLong(DueDataUtil.checkDecimalInfo(bdAccLedgerTempVo.getLoanFlushPrincipalLong(), oneHundred));
		// repay_normal_principal_long 中长期正常本金还款
		bdAccLedgerDetailInfoVO
				.setRepayNormalPrincipalLong(DueDataUtil.checkDecimalInfo(bdAccLedgerTempVo.getRepayNormalPrincipalLong(), oneHundred));
		// repay_interest 正常利息归还
		bdAccLedgerDetailInfoVO.setRepayInterest(DueDataUtil.checkDecimalInfo(bdAccLedgerTempVo.getRepayInterest(), oneHundred));
		// provision_interest 每日计提利息
		bdAccLedgerDetailInfoVO.setProvisionInterest(DueDataUtil.checkDecimalInfo(bdAccLedgerTempVo.getProvisionInterest(), oneHundred));
		// repay_overdue_principal 逾期本金还款金额
		bdAccLedgerDetailInfoVO
				.setRepayOverduePrincipal(DueDataUtil.checkDecimalInfo(bdAccLedgerTempVo.getRepayOverduePrincipal(), oneHundred));
		// into_overdue_remain_principal_short 新增短期贷款的逾期本金
		bdAccLedgerDetailInfoVO.setIntoOverdueRemainPrincipalShort(
				DueDataUtil.checkDecimalInfo(bdAccLedgerTempVo.getIntoOverdueRemainPrincipalShort(), oneHundred));
		// into_overdue_remain_principal_long 新增中长期贷款的逾期本金
		bdAccLedgerDetailInfoVO.setIntoOverdueRemainPrincipalLong(
				DueDataUtil.checkDecimalInfo(bdAccLedgerTempVo.getIntoOverdueRemainPrincipalLong(), oneHundred));
		// provision_penalty 新增表外利息
		bdAccLedgerDetailInfoVO.setProvisionPenalty(DueDataUtil.checkDecimalInfo(bdAccLedgerTempVo.getProvisionPenalty(), oneHundred));
		// repay_penalty 归还表外利息
		bdAccLedgerDetailInfoVO.setRepayPenalty(DueDataUtil.checkDecimalInfo(bdAccLedgerTempVo.getRepayPenalty(), oneHundred));
		// violate 贷款违约金
		bdAccLedgerDetailInfoVO.setViolate(DueDataUtil.checkDecimalInfo(bdAccLedgerTempVo.getViolate(), oneHundred));
		// create_time 创建时间
		bdAccLedgerDetailInfoVO.setCreateTime(DateTool.getCurrentDateTime());
		// last_modify_time 最近修改时间
		bdAccLedgerDetailInfoVO.setLastModifyTime(DateTool.getCurrentDateTime());
		return bdAccLedgerDetailInfoVO;
	}

	/**
	 * 
	 * 记录错误信息 <br>
	 * 0.1:ludayong:2019年3月8日 上午8:40:46:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年3月8日 上午8:40:46
	 * @date 2019年3月8日 上午8:40:46
	 * @version 0.1
	 */
	private void addErrorInfo(String tableName, String errorType, String errorMsg, String remark) {
		AccoutErroTempVO accoutErroTempVO = new AccoutErroTempVO();
		// 表名
		accoutErroTempVO.setTableName(tableName);
		// 错误级别
		accoutErroTempVO.setErroType(errorType);
		// 错误信息
		accoutErroTempVO.setErroMsg(errorMsg);
		// 备注
		accoutErroTempVO.setRemark(remark);
		// 创建时间
		accoutErroTempVO.setCreateData(DateTool.getCurrentDateTime());
		// 修改时间
		accoutErroTempVO.setLastModifyTime(DateTool.getCurrentDateTime());
		// 记录错误信息
		accoutErroTempService.insert(accoutErroTempVO);
	}

	/**
	 * 
	 * 校验并账文件是否正确 <br>
	 * 0.1:ludayong:2019年5月16日 上午9:45:16:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年5月16日 上午9:45:16
	 * @date 2019年5月16日 上午9:45:16
	 * @version 0.1
	 */
	public boolean checkAccLedgerFile(String filePath) {
		logger.info("**************************校验并账文件开始**************************");
		boolean result = false;
		// 文件读取内容
		String context = "";
		try {
			// 读取并账文件首行内容
			context = DueDataUtil.getLineContext(filePath, 1);
			// 读取的文件内容非空
			if (!StringUtil.isNullorBank(context)) {
				String[] contexts = context.split(DATA_SEPARATOR_C);
				// 读取到的文件内容列数是否正确
				if (contexts.length == BD_ACC_LEDGER_COLNUM) {
					result = true;
				} else {
					String errorMsg = "校验并账文件不通过";
					String remark = "校验并账文件不通过，错误信息：读取到并账文件列数为[" + contexts.length + "]，实际并账文件列数为[" + BD_ACC_LEDGER_COLNUM + "]";
					String tableName = "bd_acc_ledger";
					addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, remark);
					logger.error(remark);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			String errorMsg = "读取并账文件出错";
			String remark = "读取并账文件出错，错误信息：" + e.getMessage();
			String tableName = "bd_acc_ledger";
			addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, remark);
			logger.error(remark);
		}
		logger.info("**************************校验并账文件结束**************************结果[" + result + "]");
		return result;
	}

	/**
	 * 
	 * 流水号生成 <br>
	 * 0.1:ludayong:2019年5月7日 下午4:00:13:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年5月7日 下午4:00:13
	 * @date 2019年5月7日 下午4:00:13
	 * @version 0.1
	 */
	public String generateSeqNo(String type, PatternDescriptor pattern) {
		PatternedLimitableSeqService sequenceService = SpringContextUtils.getBean(PatternedLimitableSeqService.class);
		String lmtContNo = sequenceService.getPatternedSequence(type, pattern);
		return lmtContNo;
	}

	/**
	 * 
	 * 校验百度并账文件标准化信息是否正确 <br>
	 * 0.1:ludayong:2019年7月19日 下午12:26:48:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年7月19日 下午12:26:48
	 * @date 2019年7月19日 下午12:26:48
	 * @version 0.1
	 */
	public boolean checkBdAccLedgerListInfo() {
		logger.info("**************************校验百度并账文件标准化信息开始**************************");
		boolean result = true;
		try {
			// 百度并账文件标准化信息
			BdAccLedgerVO bdAccLedgerVo = new BdAccLedgerVO();
			// 合作方代码
			bdAccLedgerVo.setPartnerCode(prtnrCd);
			// 产品类型
			bdAccLedgerVo.setProdType(prodType);
			List<BdAccLedgerVO> bdAccLedgerList = bdAccLedgerService.queryBdAccLedgerWithPartnerCodeAndProdType(bdAccLedgerVo);
			if (Objects.nonNull(bdAccLedgerList) && !bdAccLedgerList.isEmpty()) {
				for (BdAccLedgerVO bdAccLedgerVOInfo : bdAccLedgerList) {
					if (StringUtil.isNullorBank(bdAccLedgerVOInfo.getIndexCode())
							|| !indexMap.containsKey(bdAccLedgerVOInfo.getIndexCode())) {
						result = false;
						String errorMsg = "校验百度并账文件标准化信息不通过！";
						String remark = "校验百度并账文件标准化信息不通过，指标信息：[" + bdAccLedgerVOInfo.getIndexCode() + "]，为空或者不存在！";
						String tableName = "bd_acc_ledger";
						addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, remark);
						logger.error(remark);
						break;
					}
				}
			}
		} catch (Exception e) {
			result = false;
			String errorMsg = "校验百度并账文件标准化信息出错！";
			String remark = "校验百度并账文件标准化信息出错，错误信息：" + e.getMessage();
			String tableName = "bd_acc_ledger";
			addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, remark);
			logger.error(remark);
		}
		logger.info("**************************校验百度并账文件标准化信息结束**************************结果[" + result + "]");
		return result;
	}

	/**
	 * 
	 * 校验百度并账文件处理入参信息是否正确 <br>
	 * 0.1:ludayong:2019年7月19日 下午12:26:48:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年7月19日 下午12:26:48
	 * @date 2019年7月19日 下午12:26:48
	 * @version 0.1
	 */
	public boolean checkParamInfo(String curDate, String prdCode, String type) {
		logger.info("**************************校验百度并账文件处理入参信息开始**************************");
		boolean result = false;
		try {
			if (StringUtil.isNullorBank(curDate) || StringUtil.isNullorBank(prdCode) || StringUtil.isNullorBank(type)) {
				String tableName = "prd_info";
				String errorMsg = "百度并账文件处理校验入参信息不正确，入参信息不能为空，批次日期：" + curDate + "，产品编号：" + prdCode + "，业务类型：" + type;
				addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, errorMsg);
				logger.error(errorMsg);
				return result;
			}

			if (!(PrdInfoEnum.ZXD.getPrdId().equals(prdCode) || PrdInfoEnum.MYD.getPrdId().equals(prdCode))) {
				String tableName = "prd_info";
				String errorMsg = "百度并账文件处理校验入参信息不正确，产品信息非满易贷、尊享贷产品，产品编号：" + prdCode;
				addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, errorMsg);
				logger.error(errorMsg);
				return result;
			}

			if (!(TYPE_LF.equals(type) || TYPE_LE.equals(type))) {
				String tableName = "prd_info";
				String errorMsg = "百度并账文件处理校验入参信息不正确，业务类型：" + type;
				addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, errorMsg);
				logger.error(errorMsg);
				return result;
			}
			result = true;
		} catch (Exception e) {
			result = false;
			String errorMsg = "校验百度并账文件处理入参信息出错！";
			String remark = "校验百度并账文件处理入参信息出错，错误信息：" + e.getMessage();
			String tableName = "bd_acc_ledger";
			addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, remark);
			logger.error(remark);
		}
		logger.info("**************************校验百度并账文件处理入参信息结束**************************结果[" + result + "]");
		return result;
	}
}
